import React, { useRef, useState, useEffect } from 'react';
import {
    Box,
    Paper,
    Typography,
    Grid as MuiGrid,
    IconButton,
    Tooltip,
    FormControl,
    InputLabel,
    Select,
    MenuItem,
    Slider,
    TextField,
    InputAdornment,
    Button,
    Divider,
    Menu,
    ListItemIcon,
    ListItemText,
    Tab,
    Tabs,
    Stack,
    CircularProgress,
    FormControlLabel,
    Switch
} from '@mui/material';
import {
    Palette as PaletteIcon,
    DeleteOutline as DeleteIcon,
    Save as SaveIcon,
    Undo as UndoIcon,
    Redo as RedoIcon,
    FileUpload as FileUploadIcon,
    FileDownload as FileDownloadIcon,
    ViewInAr as ViewInArIcon,
    Add as AddIcon
} from '@mui/icons-material';
import SphereIcon from './icons/SphereIcon';
import CubeIcon from './icons/CubeIcon';
import CylinderIcon from './icons/CylinderIcon';
import ConeIcon from './icons/ConeIcon';
import TorusIcon from './icons/TorusIcon';
import PyramidIcon from './icons/PyramidIcon';
import { styled } from '@mui/material/styles';
import { exportModel } from './exporters/ModelExporter';
import ThreeModelScene from './ThreeModelScene';
import * as THREE from 'three';
// 导入IndexedDB键值存储库
import * as idbKeyval from 'idb-keyval';

// 设置全局idbKeyval供其他函数使用
if (typeof window !== 'undefined') {
    window.idbKeyval = idbKeyval;
}

// 样式化的Tab
const StyledTab = styled(Tab)(({ theme }) => ({
    textTransform: 'none',
    fontSize: '0.875rem',
    fontWeight: 500,
    minHeight: 42,
    padding: '0 12px',
    '&.Mui-selected': {
        color: theme.palette.primary.main,
        fontWeight: 600
    }
}));

// 主编辑器组件
const ThreeModelEditor = ({
    initialModel = null,
    onSave,
    modelName = '',
    modelDescription = ''
}) => {
    // 场景对象状态
    const [objects, setObjects] = useState([]);
    const [selectedObject, setSelectedObject] = useState(null);
    const [previewObject, setPreviewObject] = useState(null);
    const [history, setHistory] = useState([]);
    const [historyIndex, setHistoryIndex] = useState(-1);

    // 控制面板状态
    const [activeTab, setActiveTab] = useState(0);
    // 辅助工具显示控制
    const [showHelpers, setShowHelpers] = useState(true);
    // 编辑区域高度控制
    const [editorHeight, setEditorHeight] = useState(600);

    // 选中对象的属性状态
    const [selectedObjectColor, setSelectedObjectColor] = useState('#3366FF');
    const [selectedObjectSize, setSelectedObjectSize] = useState({ width: 1, height: 1, depth: 1 });
    const [selectedObjectRadius, setSelectedObjectRadius] = useState(1);
    const [selectedObjectType, setSelectedObjectType] = useState('');
    const [selectedObjectCylinderProps, setSelectedObjectCylinderProps] = useState({ radius: 1, height: 2 });
    const [selectedObjectConeProps, setSelectedObjectConeProps] = useState({ radius: 1, height: 2 });
    const [selectedObjectTorusProps, setSelectedObjectTorusProps] = useState({ radius: 1, tube: 0.4 });
    const [selectedObjectPyramidProps, setSelectedObjectPyramidProps] = useState({ width: 1, height: 1.5, depth: 1 });
    // 添加选中对象的旋转状态
    const [selectedObjectRotation, setSelectedObjectRotation] = useState({ x: 0, y: 0, z: 0 });
    // 添加变换控制模式
    const [transformMode, setTransformMode] = useState('translate'); // 'translate', 'rotate', 'scale'

    // 新对象属性状态
    const [newObjectType, setNewObjectType] = useState('box');
    const [newObjectColor, setNewObjectColor] = useState('#3366FF');
    const [boxSize, setBoxSize] = useState({ width: 1, height: 1, depth: 1 });
    const [sphereRadius, setSphereRadius] = useState(1);
    const [cylinderSize, setCylinderSize] = useState({ radius: 1, height: 2 });
    const [coneSize, setConeSize] = useState({ radius: 1, height: 2 });
    const [torusSize, setTorusSize] = useState({ radius: 1, tube: 0.4 });
    const [pyramidSize, setPyramidSize] = useState({ width: 1, height: 1.5, depth: 1 });

    // 文件上传引用
    const fileInputRef = useRef(null);

    // 导出菜单状态
    const [downloadMenuAnchor, setDownloadMenuAnchor] = useState(null);
    const [downloadInProgress, setDownloadInProgress] = useState(false);
    const [exportFormat, setExportFormat] = useState('json');

    // 添加外部模型集合状态
    const [externalModels, setExternalModels] = useState([]);

    // 添加模型加载状态
    const [modelLoading, setModelLoading] = useState(false);
    const [modelLoadingText, setModelLoadingText] = useState('');

    // 初始化或加载现有模型
    useEffect(() => {
        // 检查sessionStorage中是否有从材料库导入的材料
        try {
            const importedMaterialJSON = sessionStorage.getItem('importedMaterial');
            if (importedMaterialJSON) {
                const importedMaterial = JSON.parse(importedMaterialJSON);
                console.log('从材料库导入的材料:', importedMaterial);

                // 清除sessionStorage中的数据，防止重复导入
                sessionStorage.removeItem('importedMaterial');

                // 如果导入的是模型文件（如OBJ, STL, GLB等）
                if (importedMaterial.format) {
                    // 构建一个虚拟文件对象
                    if (importedMaterial.serverModelUrl) {
                        // 如果有URL，使用fetch获取文件内容
                        fetch(importedMaterial.serverModelUrl)
                            .then(response => response.blob())
                            .then(blob => {
                                const file = new File([blob], importedMaterial.fileName || `imported.${importedMaterial.format}`, {
                                    type: `model/${importedMaterial.format}`
                                });
                                importExternalModel(file, importedMaterial.format);
                            })
                            .catch(error => {
                                console.error('获取模型文件失败:', error);
                                alert('导入模型失败: ' + error.message);
                            });
                    } else {
                        alert('无法导入模型: 缺少模型URL');
                    }
                }
                // 如果是材质，可以添加材质处理代码
            }
        } catch (error) {
            console.error('处理导入材料时出错:', error);
        }

        if (initialModel && initialModel.geometry) {
            const geometry = initialModel.geometry;

            let initialObjects = [];

            // 检查几何体类型
            if (geometry.type === 'external_model') {
                // *** 新增日志：检查加载时的 metadata ***
                console.log('[useEffect Load] 处理主几何体 external_model，检查 metadata:', geometry.metadata);

                initialObjects = [{
                    type: 'external_model',
                    color: geometry.color || '#3366FF',
                    externalId: geometry.metadata?.externalId, // 读取 externalId
                    cacheId: geometry.metadata?.cacheId, // *** 新增：读取 cacheId ***
                    format: geometry.format,
                    fileName: geometry.file,
                    position: {
                        x: geometry.position?.x || 0,
                        y: geometry.position?.y || 0,
                        z: geometry.position?.z || 0
                    },
                    rotation: geometry.rotation || { x: 0, y: 0, z: 0 },
                    scale: geometry.scale || { x: 1, y: 1, z: 1 },
                    needsReimport: false,
                    isFromSave: true,
                    properties: geometry.properties || ['file', 'color', 'material', 'position', 'rotation', 'scale'],
                    material: geometry.material || { color: geometry.color || '#3366FF' },
                    serverModelId: geometry.serverModelId || geometry.metadata?.serverModelId,
                    serverModelUrl: geometry.serverModelUrl || geometry.filePath || geometry.metadata?.serverModelUrl
                }];

                // 根据是否有服务器URL调整提示
                if (geometry.serverModelUrl || geometry.filePath) {
                    console.log('检测到带有服务器路径的外部模型，将尝试从服务器加载');

                    // 如果有服务器URL，尝试从服务器加载模型
                    setTimeout(() => {
                        tryLoadModelFromServer(initialObjects[0]);
                    }, 1000);
                } else {
                    console.log('检测到外部模型，如需查看完整模型请导入原始文件。');
                }
            } else if (geometry.type === 'cube' && geometry.metadata && geometry.metadata.isExternalModel) {
                // 向后兼容：处理旧版本保存为cube的外部模型
                console.log('检测到旧版本外部模型数据:', geometry.metadata);
                initialObjects = [{
                    type: 'external_model',
                    color: geometry.color || '#3366FF',
                    externalId: geometry.metadata.externalId,
                    format: geometry.metadata.format,
                    fileName: geometry.metadata.fileName,
                    position: {
                        x: geometry.position?.x || 0,
                        y: geometry.position?.y || 0,
                        z: geometry.position?.z || 0
                    },
                    rotation: geometry.rotation || { x: 0, y: 0, z: 0 },
                    scale: geometry.metadata.scale || { x: 1, y: 1, z: 1 },
                    needsReimport: true // 标记需要重新导入
                }];

                // 提示用户需要重新导入 - 改为使用控制台
                console.warn('检测到旧版本保存的外部模型，请重新导入原始文件以恢复完整模型。');
            } else if (geometry.type === 'cube') {
                initialObjects = [{
                    type: 'box',
                    color: geometry.color || '#3366FF',
                    size: {
                        width: geometry.dimensions?.width || 1,
                        height: geometry.dimensions?.height || 1,
                        depth: geometry.dimensions?.depth || 1
                    },
                    position: {
                        x: geometry.position?.x || 0,
                        y: geometry.position?.y || 0,
                        z: geometry.position?.z || 0
                    },
                    rotation: geometry.rotation || { x: 0, y: 0, z: 0 }
                }];
            } else if (geometry.type === 'sphere') {
                initialObjects = [{
                    type: 'sphere',
                    color: geometry.color || '#3366FF',
                    radius: geometry.dimensions?.radius || 1,
                    position: {
                        x: geometry.position?.x || 0,
                        y: geometry.position?.y || 0,
                        z: geometry.position?.z || 0
                    },
                    rotation: geometry.rotation || { x: 0, y: 0, z: 0 }
                }];
            } else {
                // 默认处理其他几何体类型
                console.log(`加载默认几何体类型 ${geometry.type}`);
                initialObjects = [{
                    type: geometry.type === 'cylinder' ? 'cylinder' :
                        geometry.type === 'cone' ? 'cone' :
                            geometry.type === 'torus' ? 'torus' :
                                geometry.type === 'pyramid' ? 'pyramid' : 'box',
                    color: geometry.color || '#3366FF',
                    position: {
                        x: geometry.position?.x || 0,
                        y: geometry.position?.y || 0,
                        z: geometry.position?.z || 0
                    },
                    rotation: geometry.rotation || { x: 0, y: 0, z: 0 }
                }];

                // 根据类型设置额外属性
                const obj = initialObjects[0];
                if (obj.type === 'cylinder' || obj.type === 'cone') {
                    obj.radius = geometry.dimensions?.radius || 1;
                    obj.height = geometry.dimensions?.height || 2;
                } else if (obj.type === 'torus') {
                    obj.radius = geometry.dimensions?.radius || 1;
                    obj.tube = geometry.dimensions?.tube || 0.4;
                } else if (obj.type === 'pyramid') {
                    obj.size = {
                        width: geometry.dimensions?.width || 1,
                        height: geometry.dimensions?.height || 1.5,
                        depth: geometry.dimensions?.depth || 1
                    };
                } else if (obj.type === 'box') {
                    obj.size = {
                        width: geometry.dimensions?.width || 1,
                        height: geometry.dimensions?.height || 1,
                        depth: geometry.dimensions?.depth || 1
                    };
                }

                console.log(`创建了默认几何体:`, obj);
            }

            // 加载额外的对象
            if (initialModel.additionalObjects && initialModel.additionalObjects.length > 0) {
                console.log(`加载${initialModel.additionalObjects.length}个额外对象`);

                for (const obj of initialModel.additionalObjects) {
                    console.log(`加载额外对象:`, obj.type, obj.position);

                    // 优先处理external_model类型
                    if (obj.type === 'external_model') {
                        // *** 新增日志：检查加载时的 metadata ***
                        console.log(`[useEffect Load] 处理额外对象 ${obj.file} external_model，检查 metadata:`, obj.metadata);

                        const externalObj = {
                            type: 'external_model',
                            color: obj.color || '#3366FF',
                            externalId: obj.metadata?.externalId, // 读取 externalId
                            cacheId: obj.metadata?.cacheId, // *** 新增：读取 cacheId ***
                            format: obj.format,
                            fileName: obj.file,
                            position: {
                                x: obj.position?.x || 0,
                                y: obj.position?.y || 0,
                                z: obj.position?.z || 0
                            },
                            rotation: obj.rotation || { x: 0, y: 0, z: 0 },
                            scale: obj.scale || { x: 1, y: 1, z: 1 },
                            needsReimport: false,
                            isFromSave: true,
                            properties: obj.properties || ['file', 'color', 'material', 'position', 'rotation', 'scale'],
                            material: obj.material || { color: obj.color || '#3366FF' },
                            serverModelId: obj.serverModelId || obj.metadata?.serverModelId,
                            serverModelUrl: obj.serverModelUrl || obj.filePath || obj.metadata?.serverModelUrl
                        };
                        initialObjects.push(externalObj);
                        console.log(`添加外部模型:`, externalObj.fileName);

                        // 如果有服务器URL，尝试加载
                        if (externalObj.serverModelUrl) {
                            // 使用setTimeout调用，避免堵塞UI
                            setTimeout(() => {
                                tryLoadModelFromServer(externalObj);
                            }, 1500 + initialObjects.length * 500); // 错开时间加载
                        }
                    }
                    // 处理旧版本保存的外部模型
                    else if (obj.type === 'cube' && obj.metadata && obj.metadata.isExternalModel) {
                        initialObjects.push({
                            type: 'external_model',
                            color: obj.color || '#3366FF',
                            externalId: obj.metadata.externalId,
                            format: obj.metadata.format,
                            fileName: obj.metadata.fileName,
                            position: {
                                x: obj.position?.x || 0,
                                y: obj.position?.y || 0,
                                z: obj.position?.z || 0
                            },
                            rotation: obj.rotation || { x: 0, y: 0, z: 0 },
                            scale: obj.metadata.scale || { x: 1, y: 1, z: 1 },
                            needsReimport: true, // 标记旧版需要重新导入
                            // 添加符合后端要求的属性
                            properties: ['file', 'color', 'material', 'position', 'rotation', 'scale'],
                            material: { color: obj.color || '#3366FF' }
                        });
                        console.log(`添加旧版外部模型`);
                    } else if (obj.type === 'cube') {
                        initialObjects.push({
                            type: 'box',
                            color: obj.color || '#3366FF',
                            size: {
                                width: obj.dimensions?.width || 1,
                                height: obj.dimensions?.height || 1,
                                depth: obj.dimensions?.depth || 1
                            },
                            position: {
                                x: obj.position?.x || 0,
                                y: obj.position?.y || 0,
                                z: obj.position?.z || 0
                            },
                            rotation: obj.rotation || { x: 0, y: 0, z: 0 }
                        });
                        console.log(`添加立方体`);
                    } else if (obj.type === 'sphere') {
                        initialObjects.push({
                            type: 'sphere',
                            color: obj.color || '#3366FF',
                            radius: obj.dimensions?.radius || 1,
                            position: {
                                x: obj.position?.x || 0,
                                y: obj.position?.y || 0,
                                z: obj.position?.z || 0
                            },
                            rotation: obj.rotation || { x: 0, y: 0, z: 0 }
                        });
                        console.log(`添加球体`);
                    } else if (obj.type === 'cylinder') {
                        initialObjects.push({
                            type: 'cylinder',
                            color: obj.color || '#3366FF',
                            radius: obj.dimensions?.radius || 1,
                            height: obj.dimensions?.height || 2,
                            position: {
                                x: obj.position?.x || 0,
                                y: obj.position?.y || 0,
                                z: obj.position?.z || 0
                            },
                            rotation: obj.rotation || { x: 0, y: 0, z: 0 }
                        });
                        console.log(`添加圆柱体`);
                    } else if (obj.type === 'cone') {
                        initialObjects.push({
                            type: 'cone',
                            color: obj.color || '#3366FF',
                            radius: obj.dimensions?.radius || 1,
                            height: obj.dimensions?.height || 2,
                            position: {
                                x: obj.position?.x || 0,
                                y: obj.position?.y || 0,
                                z: obj.position?.z || 0
                            },
                            rotation: obj.rotation || { x: 0, y: 0, z: 0 }
                        });
                        console.log(`添加圆锥体`);
                    } else if (obj.type === 'torus') {
                        initialObjects.push({
                            type: 'torus',
                            color: obj.color || '#3366FF',
                            radius: obj.dimensions?.radius || 1,
                            tube: obj.dimensions?.tube || 0.4,
                            position: {
                                x: obj.position?.x || 0,
                                y: obj.position?.y || 0,
                                z: obj.position?.z || 0
                            },
                            rotation: obj.rotation || { x: 0, y: 0, z: 0 }
                        });
                        console.log(`添加环体`);
                    } else if (obj.type === 'pyramid') {
                        initialObjects.push({
                            type: 'pyramid',
                            color: obj.color || '#3366FF',
                            size: {
                                width: obj.dimensions?.width || 1,
                                height: obj.dimensions?.height || 1.5,
                                depth: obj.dimensions?.depth || 1
                            },
                            position: {
                                x: obj.position?.x || 0,
                                y: obj.position?.y || 0,
                                z: obj.position?.z || 0
                            },
                            rotation: obj.rotation || { x: 0, y: 0, z: 0 }
                        });
                        console.log(`添加三角锥体`);
                    } else {
                        console.warn(`未知的几何体类型 ${obj.type}，无法加载`);
                    }
                }

                console.log(`完成额外对象加载，共${initialObjects.length}个对象`);
            }

            // 处理外部模型数据
            if (initialModel.externalModels && initialModel.externalModels.length > 0) {
                console.log('发现外部模型数据:', initialModel.externalModels);

                // 不再默认弹出提示，改为仅在控制台输出信息
                console.log(`发现${initialModel.externalModels.length}个外部模型记录`);

                // 加载所有外部模型记录到externalModels状态
                const newExternalModels = [...externalModels];

                for (const modelData of initialModel.externalModels) {
                    // 检查是否已经存在这个externalId的模型
                    if (!newExternalModels.some(m => m.id === modelData.id)) {
                        newExternalModels.push({
                            id: modelData.id,
                            type: 'external',
                            format: modelData.format,
                            fileName: modelData.fileName,
                            name: modelData.name || modelData.fileName.split('.')[0],
                            position: modelData.position || { x: 0, y: 0, z: 0 },
                            rotation: modelData.rotation || { x: 0, y: 0, z: 0 },
                            scale: modelData.scale || { x: 1, y: 1, z: 1 },
                            color: modelData.color || '#3366FF',
                            cacheId: modelData.cacheId || modelData.id,
                            serverModelId: modelData.serverModelId,
                            serverModelUrl: modelData.serverModelUrl,
                            importTime: modelData.importTime || new Date().toISOString()
                        });
                    }
                }

                // 如果有新模型被添加，更新externalModels状态
                if (newExternalModels.length > externalModels.length) {
                    console.log(`添加了${newExternalModels.length - externalModels.length}个外部模型记录到状态`);
                    setExternalModels(newExternalModels);
                }

                // 如果用户已经保存了很多external_model，我们可以尝试从缓存恢复它们
                const externalModelIds = initialModel.externalModels
                    .filter(model => model.cacheId)
                    .map(model => model.cacheId);

                if (externalModelIds.length > 0) {
                    // 添加到恢复队列中，稍后可能进行处理
                    console.log(`有${externalModelIds.length}个外部模型可能可以从缓存恢复`);
                }
            }

            // 使用一个标志变量避免无限循环
            const initialObjectsJson = JSON.stringify(initialObjects);
            const objectsJson = JSON.stringify(objects);

            // 只在对象数组真正发生变化时更新状态
            if (initialObjectsJson !== objectsJson) {
                setObjects(initialObjects);
                // 保存初始历史记录
                setHistory([initialObjects]);
                setHistoryIndex(0);

                // 尝试从缓存恢复外部模型
                if (initialObjects.some(obj => obj.type === 'external_model')) {
                    setTimeout(() => {
                        // 询问是否恢复，改为控制台日志
                        console.log('检测到外部模型数据，尝试自动从缓存恢复');
                        tryRestoreExternalModelsFromCache(initialObjects);
                    }, 1500);
                }
            }
        }
    }, [initialModel]);

    // 从缓存中尝试恢复外部模型
    const tryRestoreExternalModelsFromCache = async (objectsToRestore) => {
        const externalModels = objectsToRestore.filter(obj => obj.type === 'external_model');
        if (externalModels.length === 0) return;

        console.log(`[Cache Read] 开始尝试从缓存恢复 ${externalModels.length} 个外部模型`);

        let restored = 0;
        let failed = 0;

        for (const model of externalModels) {
            const modelId = model.externalId || model.cacheId;
            console.log(`[Cache Read] 处理模型: ${model.fileName || modelId}, 尝试使用 ID: ${modelId}`);

            if (!modelId) {
                console.warn('[Cache Read] 模型缺少ID，无法恢复:', model);
                failed++;
                continue;
            }

            // 尝试从缓存加载
            try {
                // 首先检查本地存储是否有此模型的信息
                const isCached = localStorage.getItem(`model_${modelId}_cached`) === "true";
                console.log(`[Cache Read] ID ${modelId} - localStorage 'cached' 标记:`, isCached);
                if (!isCached) {
                    console.warn(`[Cache Read] 模型 ${modelId} 在 localStorage 中未标记为已缓存`);
                    failed++;
                    continue;
                }

                // 获取文件信息
                const fileInfoStr = localStorage.getItem(`model_${modelId}_fileinfo`);
                console.log(`[Cache Read] ID ${modelId} - localStorage 'fileinfo' 内容:`, fileInfoStr);
                if (!fileInfoStr) {
                    console.warn(`[Cache Read] 模型 ${modelId} 在 localStorage 中缺少文件信息`);
                    failed++;
                    continue;
                }

                const fileInfo = JSON.parse(fileInfoStr);
                console.log(`[Cache Read] ID ${modelId} - 解析的文件信息:`, fileInfo);

                // 尝试从不同存储中获取模型数据
                let modelData = null;

                // 首先尝试从IndexedDB获取(使用idbKeyval库)
                if (window.idbKeyval) {
                    console.log(`[Cache Read] ID ${modelId} - 尝试从 IndexedDB 获取数据...`);
                    try {
                        modelData = await window.idbKeyval.get(`model_${modelId}_data`);
                        console.log(`[Cache Read] ID ${modelId} - IndexedDB 返回数据大小: ${modelData ? modelData.byteLength : 'null'}`);
                    } catch (e) {
                        console.warn(`[Cache Read] ID ${modelId} - 从 IndexedDB 获取模型失败:`, e);
                    }
                } else {
                    console.warn(`[Cache Read] ID ${modelId} - window.idbKeyval 不可用，跳过 IndexedDB`);
                }

                // 如果IndexedDB没有，尝试从sessionStorage获取 (这部分逻辑可能不太常用，但保留检查)
                if (!modelData && typeof sessionStorage !== 'undefined') {
                    console.log(`[Cache Read] ID ${modelId} - IndexedDB 未获取到数据，尝试 sessionStorage...`);
                    try {
                        const base64Data = sessionStorage.getItem(`model_${modelId}_data`);
                        console.log(`[Cache Read] ID ${modelId} - sessionStorage 返回数据长度: ${base64Data ? base64Data.length : 'null'}`);
                        if (base64Data) {
                            // 转换base64为ArrayBuffer
                            const binaryString = atob(base64Data);
                            const bytes = new Uint8Array(binaryString.length);
                            for (let i = 0; i < binaryString.length; i++) {
                                bytes[i] = binaryString.charCodeAt(i);
                            }
                            modelData = bytes.buffer;
                            console.log(`[Cache Read] ID ${modelId} - 从 sessionStorage 转换得到 ArrayBuffer，大小: ${modelData.byteLength}`);
                        }
                    } catch (e) {
                        console.warn(`[Cache Read] ID ${modelId} - 从 sessionStorage 获取或转换模型失败:`, e);
                    }
                }

                if (!modelData) {
                    console.warn(`[Cache Read] 未能找到模型 ${fileInfo.name} (ID: ${modelId}) 的缓存数据 (IndexedDB/sessionStorage)`);
                    failed++;
                    continue;
                }

                // 创建Blob和URL
                console.log(`[Cache Read] ID ${modelId} - 找到模型数据，创建 Blob 和 File 对象...`);
                const blob = new Blob([modelData], { type: `model/${fileInfo.format}` });
                const file = new File([blob], fileInfo.name, {
                    type: `model/${fileInfo.format}`,
                    lastModified: fileInfo.timestamp
                });

                // 导入恢复的模型
                console.log(`[Cache Read] ID ${modelId} - 调用 importExternalModel 进行恢复...`);
                // 添加 try-catch 围绕 importExternalModel 调用
                try {
                    await importExternalModel(file, fileInfo.format);
                    console.log(`[Cache Read] ID ${modelId} - 模型 ${fileInfo.name} 恢复成功！`);
                    restored++;
                } catch (importError) {
                    console.error(`[Cache Read] ID ${modelId} - 调用 importExternalModel 恢复模型 ${fileInfo.name} 时失败:`, importError);
                    failed++;
                }

            } catch (error) {
                console.error(`[Cache Read] 恢复模型 (ID: ${modelId}) 时发生意外错误:`, error);
                failed++;
            }
        }

        console.log(`[Cache Read] 缓存恢复尝试完成 - 成功: ${restored}, 失败: ${failed}`);

        // 显示恢复结果 - 使用一个简洁的提示
        if (restored > 0) {
            // 简化提示
            console.log(`成功恢复 ${restored} 个模型，失败 ${failed} 个`);
            if (failed > 0) {
                alert(`已恢复${restored}个模型，${failed}个模型需要重新导入`);
            }
        } else if (externalModels.length > 0) {
            // 只有在有模型但全部恢复失败时才提示
            alert('未能恢复任何模型，请手动导入模型文件');
        }
    };

    // 当选中对象变化时，更新选中对象的属性状态
    useEffect(() => {
        if (selectedObject !== null && objects[selectedObject]) {
            const obj = objects[selectedObject];
            setSelectedObjectColor(obj.color);
            setSelectedObjectType(obj.type);

            // 初始化旋转状态
            setSelectedObjectRotation(obj.rotation || { x: 0, y: 0, z: 0 });

            switch (obj.type) {
                case 'box':
                    setSelectedObjectSize(obj.size);
                    break;
                case 'sphere':
                    setSelectedObjectRadius(obj.radius);
                    break;
                case 'cylinder':
                    setSelectedObjectCylinderProps({
                        radius: obj.radius,
                        height: obj.height
                    });
                    break;
                case 'cone':
                    setSelectedObjectConeProps({
                        radius: obj.radius,
                        height: obj.height
                    });
                    break;
                case 'torus':
                    setSelectedObjectTorusProps({
                        radius: obj.radius,
                        tube: obj.tube
                    });
                    break;
                case 'pyramid':
                    setSelectedObjectPyramidProps(obj.size);
                    break;
                default:
                    break;
            }
        }
    }, [selectedObject, objects]);

    // 创建预览对象
    const createPreviewObject = () => {
        let newPreview;

        switch (newObjectType) {
            case 'box':
                newPreview = {
                    type: 'box',
                    color: newObjectColor,
                    size: boxSize,
                    position: { x: 0, y: 0, z: 0 }
                };
                break;
            case 'sphere':
                newPreview = {
                    type: 'sphere',
                    color: newObjectColor,
                    radius: sphereRadius,
                    position: { x: 0, y: 0, z: 0 }
                };
                break;
            case 'cylinder':
                newPreview = {
                    type: 'cylinder',
                    color: newObjectColor,
                    radius: cylinderSize.radius,
                    height: cylinderSize.height,
                    position: { x: 0, y: 0, z: 0 }
                };
                break;
            case 'cone':
                newPreview = {
                    type: 'cone',
                    color: newObjectColor,
                    radius: coneSize.radius,
                    height: coneSize.height,
                    position: { x: 0, y: 0, z: 0 }
                };
                break;
            case 'torus':
                newPreview = {
                    type: 'torus',
                    color: newObjectColor,
                    radius: torusSize.radius,
                    tube: torusSize.tube,
                    position: { x: 0, y: 0, z: 0 }
                };
                break;
            case 'pyramid':
                newPreview = {
                    type: 'pyramid',
                    color: newObjectColor,
                    size: pyramidSize,
                    position: { x: 0, y: 0, z: 0 }
                };
                break;
            default:
                newPreview = {
                    type: 'box',
                    color: newObjectColor,
                    size: boxSize,
                    position: { x: 0, y: 0, z: 0 }
                };
        }

        setPreviewObject(newPreview);
    };

    // 处理对象放置
    const handleObjectPlaced = (newObject, index) => {
        let newObjects;

        if (index !== undefined) {
            // 更新现有对象的位置
            newObjects = [...objects];
            newObjects[index] = newObject;

            // 如果是外部模型，同时更新externalModels中的对应模型
            if (newObject.type === 'external_model' && newObject.externalId) {
                const modelIndex = externalModels.findIndex(model => model.id === newObject.externalId);
                if (modelIndex !== -1) {
                    const updatedExternalModels = [...externalModels];
                    updatedExternalModels[modelIndex] = {
                        ...updatedExternalModels[modelIndex],
                        position: newObject.position,
                        rotation: newObject.rotation,
                        scale: newObject.scale,
                        color: newObject.color // 更新颜色属性
                    };
                    setExternalModels(updatedExternalModels);
                }
            }
        } else {
            // 添加新对象
            newObjects = [...objects, newObject];
            // 选择新添加的对象
            setSelectedObject(newObjects.length - 1);
        }

        setObjects(newObjects);

        // 更新历史记录
        const newHistory = history.slice(0, historyIndex + 1);
        newHistory.push(newObjects);
        setHistory(newHistory);
        setHistoryIndex(historyIndex + 1);
    };

    // 处理对象移除
    const handleObjectRemoved = (index) => {
        const newObjects = objects.filter((_, i) => i !== index);
        setObjects(newObjects);

        // 更新历史记录
        const newHistory = history.slice(0, historyIndex + 1);
        newHistory.push(newObjects);
        setHistory(newHistory);
        setHistoryIndex(historyIndex + 1);

        setSelectedObject(null);
    };

    // 删除选中的物体
    const deleteSelectedObject = () => {
        if (selectedObject === null) return;
        handleObjectRemoved(selectedObject);
    };

    // 撤销操作
    const undo = () => {
        if (historyIndex > 0) {
            setHistoryIndex(historyIndex - 1);
            setObjects(history[historyIndex - 1]);
            setSelectedObject(null);
        }
    };

    // 重做操作
    const redo = () => {
        if (historyIndex < history.length - 1) {
            setHistoryIndex(historyIndex + 1);
            setObjects(history[historyIndex + 1]);
            setSelectedObject(null);
        }
    };

    // 保存模型
    const handleSave = async () => {
        if (objects.length === 0) {
            alert('请先添加至少一个3D对象');
            return;
        }

        try {
            // 显示保存进度
            setModelLoading(true);
            setModelLoadingText('正在保存模型...');

            // *** 不再单独上传每个模型，而是在本地处理好所有数据 ***

            // *** 新增：在转换前，强制同步 objects 数组中外部模型的信息 ***
            const syncedObjects = objects.map(obj => {
                if (obj.type === 'external_model' && obj.externalId && externalModels.length > 0) {
                    const sourceModel = externalModels.find(m => m.id === obj.externalId);
                    if (sourceModel) {
                        // 返回一个合并了最新信息的新对象
                        return {
                            ...obj,
                            serverModelId: sourceModel.serverModelId || obj.serverModelId,
                            serverModelUrl: sourceModel.serverModelUrl || obj.serverModelUrl,
                            cacheId: sourceModel.cacheId || obj.cacheId || obj.externalId,
                            fileName: sourceModel.fileName || obj.fileName,
                            format: sourceModel.format || obj.format
                        };
                    }
                }
                return obj; // 其他类型或未找到源信息的对象保持不变
            });
            console.log("[handleSave] 同步后的 Objects 数组:", syncedObjects);
            // *** 新增结束 ***

            // 将编辑器数据转换为模型格式
            const modelData = {
                name: modelName,
                description: modelDescription,
                geometry: {},
                additionalObjects: [],
                externalModels: [] // 初始化为空，后面会被覆盖
            };

            // 首个对象作为主几何体 (使用同步后的数组)
            const firstObject = syncedObjects[0];

            // 创建转换函数处理不同类型的对象
            const convertObjectToGeometry = (obj) => {
                let geometry = {
                    position: obj.position,
                    rotation: obj.rotation || { x: 0, y: 0, z: 0 },
                    color: obj.color
                };

                switch (obj.type) {
                    case 'box':
                        geometry.type = 'cube';
                        geometry.dimensions = {
                            width: obj.size.width,
                            height: obj.size.height,
                            depth: obj.size.depth
                        };
                        break;
                    case 'sphere':
                        geometry.type = 'sphere';
                        geometry.dimensions = {
                            radius: obj.radius,
                            segments: 32
                        };
                        break;
                    case 'cylinder':
                        geometry.type = 'cylinder';
                        geometry.dimensions = {
                            radius: obj.radius,
                            height: obj.height,
                            segments: 32
                        };
                        break;
                    case 'cone':
                        geometry.type = 'cone';
                        geometry.dimensions = {
                            radius: obj.radius,
                            height: obj.height,
                            segments: 32
                        };
                        break;
                    case 'torus':
                        geometry.type = 'torus';
                        geometry.dimensions = {
                            radius: obj.radius,
                            tube: obj.tube,
                            tubularSegments: 100,
                            radialSegments: 16
                        };
                        break;
                    case 'pyramid':
                        geometry.type = 'pyramid';
                        geometry.dimensions = {
                            width: obj.size.width,
                            height: obj.size.height,
                            depth: obj.size.depth
                        };
                        break;
                    case 'external_model':
                        geometry.type = 'external_model';
                        geometry.file = obj.fileName;
                        geometry.format = obj.format;
                        geometry.scale = obj.scale || { x: 1, y: 1, z: 1 };
                        geometry.properties = ['file', 'color', 'material', 'position', 'rotation', 'scale'];
                        geometry.material = { color: obj.color };

                        // 添加文件数据引用 - 附加原始二进制数据供onSave回调使用
                        const sourceModel = externalModels.find(m => m.id === obj.externalId);
                        if (sourceModel && sourceModel.originalFile) {
                            geometry.originalFile = sourceModel.originalFile;
                        }

                        // 直接使用同步后的 obj 属性
                        if (obj.serverModelId) {
                            geometry.serverModelId = obj.serverModelId;
                        }
                        if (obj.serverModelUrl) {
                            geometry.serverModelUrl = obj.serverModelUrl;
                            geometry.filePath = obj.serverModelUrl;
                        }

                        geometry.metadata = {
                            externalId: obj.externalId,
                            cacheId: obj.cacheId, // 使用同步后的 cacheId
                            originalType: 'external_model',
                            serverModelId: obj.serverModelId,
                            serverModelUrl: obj.serverModelUrl
                        };
                        break;
                    default:
                        geometry.type = 'cube';
                        geometry.dimensions = {
                            width: 1,
                            height: 1,
                            depth: 1
                        };
                }

                return geometry;
            };

            // 处理主几何体
            modelData.geometry = convertObjectToGeometry(firstObject);

            // 添加其他几何体 - 确保所有对象都被添加，不限制数量 (使用同步后的数组)
            if (syncedObjects.length > 1) {
                console.log(`保存${syncedObjects.length - 1}个额外几何体`);
                for (let i = 1; i < syncedObjects.length; i++) {
                    const additionalObj = convertObjectToGeometry(syncedObjects[i]);
                    modelData.additionalObjects.push(additionalObj);
                    console.log(`添加额外几何体 ${i}:`, syncedObjects[i].type, additionalObj);
                }
            }

            // 收集所有外部模型的基本信息
            const externalModelsSaveData = [];
            if (externalModels.length > 0) {
                for (const model of externalModels) {
                    // 检查这个模型是否被使用在任何对象中
                    const isUsed = syncedObjects.some(obj =>
                        obj.type === 'external_model' && obj.externalId === model.id);

                    // 只保存被使用的模型
                    if (isUsed) {
                        // 确保保存的数据包含服务器信息（如果存在）
                        const modelSaveData = {
                            id: model.id,
                            format: model.format,
                            name: model.name,
                            fileName: model.fileName,
                            position: model.position,
                            rotation: model.rotation,
                            scale: model.scale,
                            color: model.color,
                            cacheId: model.id, // 使用 id 作为 cacheId
                            properties: ['file', 'color', 'material', 'position', 'rotation', 'scale'],
                            serverModelId: model.serverModelId, // 添加 serverModelId
                            serverModelUrl: model.serverModelUrl, // 添加 serverModelUrl
                            // 如果有原始文件数据，添加引用供onSave回调使用
                            originalFile: model.originalFile
                        };
                        externalModelsSaveData.push(modelSaveData);
                    }
                }
            }
            // *** 修改：确保将收集到的数据赋值给 modelData ***
            modelData.externalModels = externalModelsSaveData;

            // 打印保存的数据以便调试
            console.log("保存模型数据:", modelData);
            console.log("主几何体:", JSON.stringify(modelData.geometry, null, 2));
            console.log("额外几何体数量:", modelData.additionalObjects.length);
            console.log("外部几何体:", JSON.stringify(modelData.additionalObjects, null, 2));
            console.log("外部模型数组长度:", modelData.externalModels.length);

            // 调用保存回调 - onSave回调需要负责整个模型(包括所有外部模型文件)的保存
            setModelLoadingText('保存模型数据到服务器...');
            await onSave(modelData);

            // 隐藏加载指示器
            setModelLoading(false);

        } catch (error) {
            console.error("保存模型时出错:", error);
            setModelLoadingText('保存失败: ' + error.message);
            setTimeout(() => {
                setModelLoading(false);
                alert("保存模型失败: " + error.message);
            }, 1000);
        }
    };

    // 打开导出菜单
    const handleOpenDownloadMenu = (event) => {
        setDownloadMenuAnchor(event.currentTarget);
    };

    // 关闭导出菜单
    const handleCloseDownloadMenu = () => {
        setDownloadMenuAnchor(null);
    };

    // 导出JSON模型文件
    const exportJsonModel = () => {
        if (objects.length === 0) {
            alert('请先添加至少一个3D对象');
            return;
        }
        handleCloseDownloadMenu();

        try {
            // 构建导出数据
            const exportData = {
                name: modelName || '未命名模型',
                description: modelDescription || '',
                objects: objects,
                externalModels: externalModels.map(model => ({
                    id: model.id,
                    type: 'external',
                    format: model.format,
                    name: model.name,
                    position: model.position,
                    rotation: model.rotation,
                    scale: model.scale,
                    // 不包含originalObject，因为它无法被序列化
                }))
            };

            // 将数据转换为JSON字符串
            const jsonString = JSON.stringify(exportData, null, 2);

            // 使用数据URI方法下载
            const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(jsonString);
            const fileName = `${exportData.name || 'model'}.json`;

            const link = document.createElement('a');
            link.href = dataUri;
            link.download = fileName;
            document.body.appendChild(link);
            link.click();

            setTimeout(() => {
                document.body.removeChild(link);
            }, 100);
        } catch (error) {
            console.error('导出JSON模型失败:', error);
            alert('导出模型失败: ' + error.message);
        }
    };

    // 导出其他格式模型
    const exportModelAs = async (format) => {
        if (objects.length === 0) {
            alert('请先添加至少一个3D对象');
            return;
        }
        handleCloseDownloadMenu();

        try {
            setDownloadInProgress(true);
            const exportData = {
                name: modelName || '未命名模型',
                description: modelDescription || '',
                objects: objects,
                externalModels: externalModels // 包含外部模型数据
            };
            await exportModel(exportData, format);
        } catch (error) {
            console.error(`导出${format.toUpperCase()}模型失败:`, error);
            alert(`导出${format.toUpperCase()}模型失败: ${error.message}`);
        } finally {
            setDownloadInProgress(false);
        }
    };

    // 导入模型函数
    const importModel = (event) => {
        try {
            const file = event.target.files[0];
            if (!file) return;

            console.log('导入文件:', file.name, file.type);

            // 获取文件后缀
            const extension = file.name.split('.').pop().toLowerCase();

            // 根据文件类型处理
            if (extension === 'json') {
                // JSON格式模型
                const reader = new FileReader();

                reader.onload = (e) => {
                    try {
                        const jsonText = e.target.result;
                        const json = JSON.parse(jsonText);
                        console.log('导入的JSON数据:', json);

                        // 检查导入的模型是否具有必要的属性
                        if (!json.geometry && (!json.objects || !json.objects.length)) {
                            throw new Error('无效的模型JSON: 缺少几何体数据');
                        }

                        // 处理旧格式和新格式
                        if (json.objects && Array.isArray(json.objects)) {
                            // 旧格式 - 直接包含对象数组
                            setObjects([...objects, ...json.objects]);

                            // 更新历史记录
                            const newHistory = history.slice(0, historyIndex + 1);
                            newHistory.push([...objects, ...json.objects]);
                            setHistory(newHistory);
                            setHistoryIndex(historyIndex + 1);

                            // 提示用户导入成功 - 简化
                            console.log(`成功导入 ${json.objects.length} 个对象`);
                            return;
                        }

                        // 新格式处理 - 包含 geometry 和 additionalObjects
                        // 先创建当前对象的副本
                        const currentObjects = [...objects];
                        let importedCount = 0;
                        let needsReimportCount = 0;

                        // 处理主几何体
                        if (json.geometry) {
                            try {
                                const mainObject = convertGeometryToObject(json.geometry);
                                console.log('转换的主几何体:', mainObject);

                                // 检查是否需要重新导入
                                if (mainObject.needsReimport) {
                                    needsReimportCount++;
                                    mainObject.color = '#FF0000'; // 标记为红色
                                }

                                currentObjects.push(mainObject);
                                importedCount++;
                            } catch (error) {
                                console.error('处理主几何体错误:', error);
                            }
                        }

                        // 处理额外对象
                        if (json.additionalObjects && Array.isArray(json.additionalObjects)) {
                            json.additionalObjects.forEach(objGeometry => {
                                try {
                                    const additionalObject = convertGeometryToObject(objGeometry);
                                    console.log('转换的额外几何体:', additionalObject);

                                    // 检查是否需要重新导入
                                    if (additionalObject.needsReimport) {
                                        needsReimportCount++;
                                        additionalObject.color = '#FF0000'; // 标记为红色
                                    }

                                    currentObjects.push(additionalObject);
                                    importedCount++;
                                } catch (error) {
                                    console.error('处理额外几何体错误:', error);
                                }
                            });
                        }

                        // 设置更新后的对象列表
                        setObjects(currentObjects);

                        // 更新历史记录
                        const newHistory = history.slice(0, historyIndex + 1);
                        newHistory.push(currentObjects);
                        setHistory(newHistory);
                        setHistoryIndex(historyIndex + 1);

                        // 提示用户导入成功 - 简化提示
                        if (needsReimportCount > 0) {
                            alert(`已导入${importedCount}个对象，其中${needsReimportCount}个需要重新导入`);
                        } else if (importedCount > 0) {
                            // 只在成功导入时显示简短提示
                            console.log(`成功导入 ${importedCount} 个对象`);
                        }

                    } catch (error) {
                        console.error('解析JSON失败:', error);
                        alert('解析模型文件失败: ' + error.message);
                    }
                };

                reader.onerror = (error) => {
                    console.error('读取文件失败:', error);
                    alert('读取文件失败');
                };

                reader.readAsText(file);
            } else if (['obj', 'stl', 'glb', 'gltf'].includes(extension)) {
                // 处理外部3D模型格式
                importExternalModel(file, extension);
            } else {
                alert(`不支持的文件格式: .${extension}`);
            }
        } catch (error) {
            console.error('导入模型时出错:', error);
            alert('导入模型失败: ' + error.message);
        } finally {
            // 重置文件输入，允许再次选择相同的文件
            if (event.target) {
                try {
                    event.target.value = '';
                } catch (e) {
                    console.warn('重置文件输入失败', e);
                }
            }
        }
    };

    // 导入外部模型（OBJ, STL, GLB）
    const importExternalModel = async (file, format) => {
        let fileURL = null;

        try {
            // 显示加载状态
            setModelLoading(true);
            setModelLoadingText(`正在加载 ${file.name}...`);

            // 生成一个唯一ID，与文件名相关联
            const fileBaseName = file.name.replace(/\.[^/.]+$/, ""); // 去掉扩展名
            const modelId = `${format}-${fileBaseName}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
            console.log(`[导入] 创建新模型ID: ${modelId}`);

            // 创建一个URL对象，用于加载模型
            fileURL = URL.createObjectURL(file);
            const fileName = file.name;

            // 直接加载模型到Three.js场景
            setModelLoadingText(`加载3D模型到场景...`);
            let loader;
            let modelObject = null;

            // 选择适当的加载器
            if (format === 'obj') {
                const { OBJLoader } = await import('three/examples/jsm/loaders/OBJLoader.js');
                loader = new OBJLoader();
            } else if (format === 'stl') {
                const { STLLoader } = await import('three/examples/jsm/loaders/STLLoader.js');
                loader = new STLLoader();
            } else if (format === 'glb' || format === 'gltf') {
                const { GLTFLoader } = await import('three/examples/jsm/loaders/GLTFLoader.js');
                loader = new GLTFLoader();
            } else {
                throw new Error(`不支持的文件格式: ${format}`);
            }

            // 加载模型
            if (format === 'stl') {
                // STL加载器返回几何体
                const geometry = await new Promise((resolve, reject) => {
                    loader.load(fileURL, geo => resolve(geo), undefined, err => reject(err));
                });
                const material = new THREE.MeshStandardMaterial({ color: newObjectColor });
                modelObject = new THREE.Mesh(geometry, material);
            } else if (format === 'glb' || format === 'gltf') {
                // GLTF/GLB加载器返回场景
                const gltf = await new Promise((resolve, reject) => {
                    loader.load(fileURL, gltf => resolve(gltf), undefined, err => reject(err));
                });
                modelObject = gltf.scene;
            } else {
                // 其他格式
                modelObject = await new Promise((resolve, reject) => {
                    loader.load(fileURL, obj => resolve(obj), undefined, err => reject(err));
                });
            }

            // 计算适当的缩放
            const autoScale = (() => {
                try {
                    const box = new THREE.Box3().setFromObject(modelObject);
                    const size = box.getSize(new THREE.Vector3());
                    const maxDim = Math.max(size.x, size.y, size.z);
                    if (maxDim > 10) return 5 / maxDim;
                    if (maxDim < 0.1) return 2 / maxDim;
                    return 1;
                } catch (error) {
                    console.warn('自动调整大小失败:', error);
                    return 1;
                }
            })();

            // 设置不同模型之间的位置间隔 - 增加偏移量，使模型更分散
            const existingModels = objects.filter(obj => obj.type === 'external_model');
            const lastModelCount = existingModels.length;

            // 修改：使用更大的x偏移，并添加z轴偏移，形成网格状布局
            const offset = {
                x: (lastModelCount % 3) * 8, // 每行3个模型，x轴偏移更大
                y: 1,
                z: Math.floor(lastModelCount / 3) * 8 // 使用z轴创建行
            };

            console.log(`[导入] 检测到${existingModels.length}个现有模型，新模型将偏移 X:${offset.x} Z:${offset.z}`);

            // 开始批量处理数据更新，避免React的重渲染问题
            // 步骤1：将Three.js对象克隆并存储到externalModels中
            const newExternalModel = {
                id: modelId,
                type: 'external',
                format: format,
                originalObject: modelObject,
                fileName: fileName,
                fileBaseName: fileBaseName,
                position: { x: 0, y: 0, z: 0 },
                rotation: { x: 0, y: 0, z: 0 },
                scale: { x: autoScale, y: autoScale, z: autoScale },
                color: newObjectColor,
                name: fileBaseName,
                importTime: new Date().toISOString(),
                cacheId: modelId,
                originalFile: file
            };

            // 步骤2：创建场景对象引用
            const sceneObject = {
                type: 'external_model',
                externalId: modelId,
                position: {
                    x: offset.x,
                    y: offset.y,
                    z: offset.z
                },
                rotation: { x: 0, y: 0, z: 0 },
                scale: { x: autoScale, y: autoScale, z: autoScale },
                color: newObjectColor,
                name: fileBaseName,
                fileName: fileName,
                fileBaseName: fileBaseName,
                format: format,
                importTime: new Date().toISOString(),
                cacheId: modelId,
                properties: ['file', 'color', 'material', 'position', 'rotation', 'scale'],
                material: { color: newObjectColor },
                needsReimport: false,
                isFromSave: false
            };

            console.log(`[导入] 添加新对象，更新前: externalModels=${externalModels.length}, objects=${objects.length}`);

            // 修改：使用函数式更新确保使用最新状态，避免闭包陷阱
            setExternalModels(prevModels => [...prevModels, newExternalModel]);
            setObjects(prevObjects => [...prevObjects, sceneObject]);

            // 修改：使用函数式更新确保使用最新状态更新历史记录
            setHistory(prevHistory => {
                const newHistory = prevHistory.slice(0, historyIndex + 1);
                // 确保获取最新的对象数组
                const currentObjects = [...objects, sceneObject];
                newHistory.push(currentObjects);
                return newHistory;
            });

            setHistoryIndex(prevIndex => prevIndex + 1);

            // 修改：延长等待时间，确保状态完全更新后再选择
            setTimeout(() => {
                // 函数式获取最新状态，确保选择正确的对象
                setSelectedObject(prevSelectedObject => {
                    const newIndex = objects.length; // 这里还是使用当前闭包中的objects.length
                    console.log(`[导入] 选择新添加的对象，尝试选择索引: ${newIndex}，当前选中: ${prevSelectedObject}`);
                    return newIndex;
                });
            }, 300);

            // 缓存本地文件数据
            try {
                console.log(`[缓存] 尝试缓存模型 ID: ${modelId}`);
                // 读取文件内容
                const fileBuffer = await new Promise((resolve, reject) => {
                    const reader = new FileReader();
                    reader.onload = () => resolve(reader.result);
                    reader.onerror = reject;
                    reader.readAsArrayBuffer(file);
                });
                console.log(`[缓存] 文件 ${fileName} 读取到 ArrayBuffer，大小: ${fileBuffer.byteLength}`);

                // 存储文件信息
                const fileInfo = {
                    name: fileName,
                    format: format,
                    size: file.size,
                    timestamp: Date.now(),
                    id: modelId
                };

                // 尝试使用IndexedDB存储文件数据
                let cacheSuccess = false;
                if (window.idbKeyval && file.size < 50 * 1024 * 1024) {
                    console.log(`[缓存] 文件大小 ${file.size} 小于 50MB，尝试写入 IndexedDB...`);
                    try {
                        await window.idbKeyval.set(`model_${modelId}_data`, fileBuffer);
                        console.log(`[缓存] 模型数据已成功写入 IndexedDB for ID: ${modelId}`);
                        cacheSuccess = true;
                    } catch (idbError) {
                        console.error(`[缓存] IndexedDB 写入失败:`, idbError);
                    }
                } else if (file.size >= 50 * 1024 * 1024) {
                    console.warn(`[缓存] 文件 ${fileName} 大小超过 50MB，不写入 IndexedDB`);
                } else {
                    console.warn(`[缓存] window.idbKeyval 不可用，无法写入 IndexedDB`);
                }

                // 仅在缓存成功时标记文件已缓存
                if (cacheSuccess) {
                    localStorage.setItem(`model_${modelId}_fileinfo`, JSON.stringify(fileInfo));
                    localStorage.setItem(`model_${modelId}_cached`, "true");
                    console.log(`[缓存] 缓存成功，已设置 localStorage 标记 for ID: ${modelId}`);
                }
            } catch (cacheError) {
                console.error(`[缓存] 缓存文件 ID: ${modelId} 时发生错误:`, cacheError);
                localStorage.removeItem(`model_${modelId}_cached`);
                localStorage.removeItem(`model_${modelId}_fileinfo`);
            }

            // 关闭加载指示器
            setModelLoading(false);
            console.log(`[导入] 模型导入完成: ${fileName}, ID: ${modelId}`);

        } catch (error) {
            console.error(`导入${format.toUpperCase()}模型失败:`, error);
            setModelLoadingText(`导入失败: ${error.message || '未知错误'}`);
            setTimeout(() => {
                alert(`导入模型失败: ${error.message || '未知错误'}`);
                setModelLoading(false);
            }, 500);
        } finally {
            // 释放URL
            if (fileURL) {
                try {
                    URL.revokeObjectURL(fileURL);
                } catch (e) {
                    console.warn('释放文件URL失败', e);
                }
            }
        }
    };

    // 将模型发送到服务器（作为后台操作，不阻塞UI）
    const sendModelToServer = async (file, format, modelId) => {
        try {
            // 准备模型数据
            const fileBaseName = file.name.replace(/\.[^/.]+$/, "");
            const fileName = file.name;
            const modelData = {
                name: fileBaseName,
                description: `导入的${format.toUpperCase()}模型: ${fileName}`,
                format: format,
                color: newObjectColor,
                position: { x: 0, y: 1, z: 0 },
                rotation: { x: 0, y: 0, z: 0 },
                scale: { x: 1, y: 1, z: 1 },
                // 添加关键元数据
                externalId: modelId,
                cacheId: modelId,
                metadata: {
                    externalId: modelId,
                    cacheId: modelId,
                    originalType: 'external_model'
                }
            };

            // 导入服务
            const fileService = (await import('../services/fileService')).default;

            // 上传模型到服务器
            console.log('后台上传模型到服务器:', modelData);
            const response = await fileService.importExternalModel(file, modelData);
            console.log('模型上传成功:', response);

            // 增强对响应的解析和处理
            if (!response) {
                throw new Error('服务器未返回任何响应');
            }

            // 检查响应数据结构
            if (response.status === 400) {
                // 服务器返回400 Bad Request
                const errorMessage = response.data?.message || '请求参数错误';
                console.error('模型上传失败(400):', errorMessage);
                throw new Error(errorMessage);
            }

            if (response.status !== 201) {
                // 其他非成功状态码
                const errorMessage = response.data?.message || `服务器返回了非预期的状态码: ${response.status}`;
                console.error(`模型上传失败(${response.status}):`, errorMessage);
                throw new Error(errorMessage);
            }

            // 检查数据格式
            if (!response.data || !response.data.data) {
                console.error('服务器响应缺少data字段:', response);
                throw new Error('服务器响应格式不正确');
            }

            const responseData = response.data.data;

            // 检查必要字段
            if (!responseData.modelId) {
                console.error('服务器响应缺少modelId:', responseData);
                throw new Error('服务器响应缺少模型ID');
            }

            // 提取模型信息
            const createdModelId = responseData.modelId;
            // 文件URL可能不在直接响应中，但我们可以构建它
            const fileUrl = responseData.fileUrl || `/api/models/${createdModelId}/download`;

            // 更新对象
            const modelIndex = externalModels.findIndex(model => model.id === modelId);
            if (modelIndex !== -1) {
                const updatedExternalModels = [...externalModels];
                updatedExternalModels[modelIndex] = {
                    ...updatedExternalModels[modelIndex],
                    serverModelId: createdModelId,
                    serverModelUrl: fileUrl
                };
                setExternalModels(updatedExternalModels);

                // 同时更新场景对象
                const objectIndex = objects.findIndex(obj => obj.type === 'external_model' && obj.externalId === modelId);
                if (objectIndex !== -1) {
                    const newObjects = [...objects];
                    newObjects[objectIndex] = {
                        ...newObjects[objectIndex],
                        serverModelId: createdModelId,
                        serverModelUrl: fileUrl
                    };
                    setObjects(newObjects);
                }
            }

            // 记录到模型注册表
            try {
                const modelRegistry = JSON.parse(localStorage.getItem('externalModelRegistry') || '[]');
                modelRegistry.push({
                    id: modelId,
                    fileName: fileName,
                    fileBaseName: fileBaseName,
                    format: format,
                    importTime: new Date().toISOString(),
                    cacheId: modelId,
                    serverModelId: createdModelId,
                    serverModelUrl: fileUrl
                });
                localStorage.setItem('externalModelRegistry', JSON.stringify(modelRegistry));
            } catch (e) {
                console.warn('无法保存模型信息到本地存储:', e);
            }

            // 尝试缓存模型数据
            try {
                console.log(`[Cache Write] 尝试缓存模型 ID: ${modelId}`);
                // 读取文件内容
                const fileBuffer = await new Promise((resolve, reject) => {
                    const reader = new FileReader();
                    reader.onload = () => resolve(reader.result);
                    reader.onerror = reject;
                    reader.readAsArrayBuffer(file);
                });
                console.log(`[Cache Write] 文件 ${fileName} 读取到 ArrayBuffer，大小: ${fileBuffer.byteLength}`);

                // 存储文件信息
                const fileInfo = {
                    name: fileName,
                    format: format,
                    size: file.size,
                    timestamp: Date.now(),
                    id: modelId,
                    serverId: createdModelId,
                    serverUrl: fileUrl
                };

                // *** 修改：先尝试写入 IndexedDB，再标记缓存状态 ***
                let cacheSuccess = false;

                // 尝试使用IndexedDB存储文件数据
                if (window.idbKeyval && file.size < 50 * 1024 * 1024) {
                    console.log(`[Cache Write] 文件大小 ${file.size} 小于 50MB，尝试写入 IndexedDB...`);
                    try {
                        await window.idbKeyval.set(`model_${modelId}_data`, fileBuffer);
                        console.log(`[Cache Write] 模型数据已成功写入 IndexedDB for ID: ${modelId}`);
                        cacheSuccess = true;
                    } catch (idbError) {
                        console.error(`[Cache Write] IndexedDB 写入失败:`, idbError);
                        // 失败后尝试备用存储方式
                    }
                } else if (file.size >= 50 * 1024 * 1024) {
                    console.warn(`[Cache Write] 文件 ${fileName} 大小超过 50MB，不写入 IndexedDB`);
                } else {
                    console.warn(`[Cache Write] window.idbKeyval 不可用，无法写入 IndexedDB`);
                }

                // 仅在缓存成功时标记文件已缓存
                if (cacheSuccess) {
                    localStorage.setItem(`model_${modelId}_fileinfo`, JSON.stringify(fileInfo));
                    localStorage.setItem(`model_${modelId}_cached`, "true");
                    console.log(`[Cache Write] 缓存成功，已设置 localStorage 标记 for ID: ${modelId}`);
                }
            } catch (cacheError) {
                console.error(`[Cache Write] 缓存文件 ID: ${modelId} 时发生错误:`, cacheError);
                // 清除任何可能设置的缓存标记，确保一致性
                localStorage.removeItem(`model_${modelId}_cached`);
                localStorage.removeItem(`model_${modelId}_fileinfo`);
            }
        } catch (error) {
            console.error('后台上传模型失败:', error);
            // 这里不显示错误，因为模型已经在本地加载成功
        }
    };

    // 更新选中对象的属性 - 优化性能
    const updateSelectedObject = (updates) => {
        if (selectedObject === null) return;

        console.log(`[编辑] 更新对象 ${selectedObject}:`, updates);

        // 使用函数式更新避免闭包陷阱和不必要的重渲染
        setObjects(prevObjects => {
            const newObjects = [...prevObjects];
            const oldObject = newObjects[selectedObject];

            // 合并更新，确保不会丢失属性
            newObjects[selectedObject] = {
                ...oldObject,  // 保留原有的所有属性
                ...updates     // 应用新的更新
            };

            return newObjects;
        });

        // 如果是外部模型，同时更新externalModels数组
        const currentObject = objects[selectedObject];
        if (currentObject.type === 'external_model' && currentObject.externalId) {
            // 使用函数式更新
            setExternalModels(prevModels => {
                const modelIndex = prevModels.findIndex(model => model.id === currentObject.externalId);
                if (modelIndex === -1) return prevModels;

                const updatedModels = [...prevModels];
                // 只更新相关属性
                if (updates.color) {
                    updatedModels[modelIndex] = {
                        ...updatedModels[modelIndex],
                        color: updates.color
                    };
                }
                if (updates.scale) {
                    updatedModels[modelIndex] = {
                        ...updatedModels[modelIndex],
                        scale: updates.scale
                    };
                }
                if (updates.rotation) {
                    updatedModels[modelIndex] = {
                        ...updatedModels[modelIndex],
                        rotation: updates.rotation
                    };
                }
                if (updates.position) {
                    updatedModels[modelIndex] = {
                        ...updatedModels[modelIndex],
                        position: updates.position
                    };
                }

                return updatedModels;
            });

            // 使用短时间延迟确保状态同步更新完成后再进行选择
            setTimeout(() => {
                // 重新选择当前对象，强制更新属性面板
                setSelectedObject(selectedObject);
            }, 50);
        }

        // 使用函数式更新历史记录
        setHistory(prevHistory => {
            const newHistory = prevHistory.slice(0, historyIndex + 1);
            // 克隆当前对象数组，确保不会共享引用
            newHistory.push(JSON.parse(JSON.stringify(objects)));
            return newHistory;
        });

        setHistoryIndex(prev => prev + 1);
    };

    // 从几何体对象转换为编辑器对象
    const convertGeometryToObject = (geometry) => {
        console.log('转换几何体对象:', geometry.type);

        let objectData = {
            position: geometry.position || { x: 0, y: 0, z: 0 },
            rotation: geometry.rotation || { x: 0, y: 0, z: 0 },
            color: geometry.color || '#3366FF'
        };

        switch (geometry.type) {
            case 'cube':
                objectData.type = 'box';
                objectData.size = {
                    width: geometry.dimensions?.width || 1,
                    height: geometry.dimensions?.height || 1,
                    depth: geometry.dimensions?.depth || 1
                };
                console.log('转换立方体:', objectData.size);
                break;
            case 'sphere':
                objectData.type = 'sphere';
                objectData.radius = geometry.dimensions?.radius || 1;
                console.log('转换球体:', objectData.radius);
                break;
            case 'cylinder':
                objectData.type = 'cylinder';
                objectData.radius = geometry.dimensions?.radius || 1;
                objectData.height = geometry.dimensions?.height || 2;
                console.log('转换圆柱体:', objectData.radius, objectData.height);
                break;
            case 'cone':
                objectData.type = 'cone';
                objectData.radius = geometry.dimensions?.radius || 1;
                objectData.height = geometry.dimensions?.height || 2;
                console.log('转换圆锥体:', objectData.radius, objectData.height);
                break;
            case 'torus':
                objectData.type = 'torus';
                objectData.radius = geometry.dimensions?.radius || 1;
                objectData.tube = geometry.dimensions?.tube || 0.4;
                console.log('转换环体:', objectData.radius, objectData.tube);
                break;
            case 'pyramid':
                objectData.type = 'pyramid';
                objectData.size = {
                    width: geometry.dimensions?.width || 1,
                    height: geometry.dimensions?.height || 1.5,
                    depth: geometry.dimensions?.depth || 1
                };
                console.log('转换三角锥体:', objectData.size);
                break;
            case 'external_model':
                // 处理外部模型
                objectData = {
                    ...objectData,
                    type: 'external_model',
                    externalId: geometry.metadata?.externalId,
                    format: geometry.format,
                    fileName: geometry.file,
                    serverModelId: geometry.serverModelId || geometry.metadata?.serverModelId,
                    serverModelUrl: geometry.serverModelUrl || geometry.filePath || geometry.metadata?.serverModelUrl,
                    scale: geometry.scale || { x: 1, y: 1, z: 1 },
                    // 添加符合后端类型的属性
                    properties: geometry.properties || ['file', 'color', 'material', 'position', 'rotation', 'scale'],
                    material: geometry.material || { color: geometry.color || '#3366FF' },
                    isFromSave: true
                };
                console.log('转换外部模型:', objectData.fileName);
                break;
            default:
                console.warn(`未知的几何体类型: ${geometry.type}`);
                return null;
        }

        return objectData;
    };

    // 添加对象到场景
    const addObject = (objectData, skipHistory = false) => {
        const newObjects = [...objects, objectData];
        setObjects(newObjects);

        // 如果是外部模型，确保它也存在于externalModels中
        if (objectData.type === 'external_model' && objectData.externalId) {
            // 检查是否已经在externalModels数组中
            const existingModelIndex = externalModels.findIndex(m => m.id === objectData.externalId);
            if (existingModelIndex === -1) {
                console.log(`[addObject] 外部模型 ${objectData.externalId} 不在externalModels中，尝试添加占位符`);
                // 创建一个基本的外部模型记录
                const newExternalModel = {
                    id: objectData.externalId,
                    type: 'external',
                    format: objectData.format || 'unknown',
                    fileName: objectData.fileName || 'unknown.model',
                    position: objectData.position || { x: 0, y: 0, z: 0 },
                    rotation: objectData.rotation || { x: 0, y: 0, z: 0 },
                    scale: objectData.scale || { x: 1, y: 1, z: 1 },
                    color: objectData.color || '#3366FF',
                    importTime: new Date().toISOString()
                };
                setExternalModels(prevModels => [...prevModels, newExternalModel]);
            }
        }

        // 选择新添加的对象
        setSelectedObject(newObjects.length - 1);

        // 更新历史记录（除非指定跳过）
        if (!skipHistory) {
            const newHistory = history.slice(0, historyIndex + 1);
            newHistory.push(newObjects);
            setHistory(newHistory);
            setHistoryIndex(historyIndex + 1);
        }
    };

    // 处理导出按钮点击事件
    const handleExportClick = () => {
        if (objects.length === 0) {
            alert('请先添加至少一个3D对象');
            return;
        }

        if (exportFormat === 'json') {
            exportJsonModel();
        } else {
            exportModelAs(exportFormat);
        }
    };

    // 触发文件上传对话框
    const handleFileUploadClick = () => {
        fileInputRef.current.click();
    };

    // 从服务器加载模型
    const tryLoadModelFromServer = async (modelObj) => {
        if (!modelObj || !modelObj.serverModelUrl || !modelObj.externalId) { // 添加 externalId 检查
            console.warn('没有服务器URL或externalId，无法加载模型', modelObj);
            return;
        }

        const modelCacheId = modelObj.externalId; // 使用 externalId 作为标识

        try {
            // 显示加载状态
            setModelLoading(true);
            setModelLoadingText(`正在从服务器加载模型 ${modelObj.fileName || modelCacheId}...`);

            console.log(`尝试从服务器加载模型: ${modelObj.serverModelUrl} (ID: ${modelCacheId})`);

            // 导入服务
            const fileService = (await import('../services/fileService')).default;

            // 使用文件服务加载模型 - 假设它返回可以直接处理的数据（如Blob或ArrayBuffer）
            // 或者返回解析后的THREE对象，这取决于fileService的实现
            const loadedData = await fileService.tryLoadModelFromServer(modelObj.serverModelUrl);

            // *** 修改开始：处理加载成功后的逻辑 ***
            if (!loadedData) { // 假设失败时返回 null 或 undefined
                throw new Error('从服务器加载模型失败: 未返回有效数据');
            }

            console.log(`模型 ${modelCacheId} 数据加载成功`);

            // 检查对象数组中是否已存在此模型
            const existingObjectIndex = objects.findIndex(
                obj => obj.type === 'external_model' && obj.externalId === modelCacheId
            );

            // 只有当对象不存在时才将其添加到对象数组中
            // 这样可以避免重复添加相同的模型
            if (existingObjectIndex === -1) {
                console.log(`模型 ${modelCacheId} 为新模型，将其添加到场景中`);
                // 创建一个新的外部模型对象
                const newObject = {
                    type: 'external_model',
                    externalId: modelCacheId,
                    position: modelObj.position || { x: 0, y: 1, z: 0 },
                    rotation: modelObj.rotation || { x: 0, y: 0, z: 0 },
                    scale: modelObj.scale || { x: 1, y: 1, z: 1 },
                    color: modelObj.color || '#3366FF',
                    fileName: modelObj.fileName,
                    format: modelObj.format,
                    serverModelId: modelObj.serverModelId,
                    serverModelUrl: modelObj.serverModelUrl,
                    loaded: true,
                    needsReimport: false
                };

                // 添加到对象数组
                setObjects(prevObjects => [...prevObjects, newObject]);

                // 更新历史记录
                const newHistory = history.slice(0, historyIndex + 1);
                newHistory.push([...objects, newObject]);
                setHistory(newHistory);
                setHistoryIndex(historyIndex + 1);
            } else {
                console.log(`模型 ${modelCacheId} 已存在于场景中，更新其状态`);
                // 更新现有对象的状态
                setObjects(prevObjects => prevObjects.map(obj => {
                    if (obj.type === 'external_model' && obj.externalId === modelCacheId) {
                        return { ...obj, loaded: true, needsReimport: false };
                    }
                    return obj;
                }));
            }

            setModelLoadingText(`模型 ${modelObj.fileName || modelCacheId} 加载完成`);
            // 短暂显示成功信息后移除加载提示
            setTimeout(() => setModelLoading(false), 1500);

        } catch (error) {
            console.error(`从服务器加载模型 ${modelCacheId} 失败:`, error);
            setModelLoadingText(`加载失败: ${error.message || '服务器错误'}`);

            // 更新对象状态，标记加载失败，以便UI可以显示错误或重试选项
            setObjects(prevObjects => prevObjects.map(obj => {
                if (obj.type === 'external_model' && obj.externalId === modelCacheId) {
                    return { ...obj, loadingError: true, needsReimport: true }; // 标记错误和需要重新导入
                }
                return obj;
            }));

            // 自动隐藏加载状态
            setTimeout(() => setModelLoading(false), 3000); // 失败时显示更久
        }
    };

    // 处理多个外部模型加载的特殊逻辑 - 新增函数
    useEffect(() => {
        // 这个函数确保externalModels和objects数组的同步性
        const syncExternalModelsWithObjects = () => {
            const externalModelObjects = objects.filter(obj => obj.type === 'external_model');

            // 记录状态
            console.log('[外部模型同步] 开始同步检查:',
                'objects中外部模型数量:', externalModelObjects.length,
                'externalModels数组长度:', externalModels.length);

            let needsUpdate = false;
            const updatedExternalModels = [...externalModels];

            // 检查objects中的每个外部模型是否都在externalModels中
            externalModelObjects.forEach(obj => {
                if (!obj.externalId) return;

                const existingIndex = updatedExternalModels.findIndex(m => m.id === obj.externalId);
                if (existingIndex === -1) {
                    // objects中有模型但externalModels中没有，创建占位符
                    console.log(`[外部模型同步] 发现缺失的外部模型 ${obj.externalId}，创建占位符`);
                    updatedExternalModels.push({
                        id: obj.externalId,
                        type: 'external',
                        format: obj.format || 'unknown',
                        fileName: obj.fileName || 'unknown.model',
                        position: obj.position || { x: 0, y: 0, z: 0 },
                        rotation: obj.rotation || { x: 0, y: 0, z: 0 },
                        scale: obj.scale || { x: 1, y: 1, z: 1 },
                        color: obj.color || '#3366FF',
                        importTime: new Date().toISOString(),
                        needsReimport: true // 标记需要重新导入
                    });
                    needsUpdate = true;
                }
            });

            // 如果需要更新，设置新的externalModels状态
            if (needsUpdate) {
                console.log('[外部模型同步] 需要更新externalModels数组，新长度:', updatedExternalModels.length);
                setExternalModels(updatedExternalModels);
            } else {
                console.log('[外部模型同步] 无需更新externalModels数组');
            }
        };

        // 只在有外部模型时执行
        if (objects.some(obj => obj.type === 'external_model')) {
            syncExternalModelsWithObjects();
        }
    }, [objects, externalModels]);

    return (
        <Paper sx={{ p: 3, borderRadius: 2, mb: 4 }}>
            <Typography variant="h6" gutterBottom>
                3D模型查看器
            </Typography>
            <Divider sx={{ mb: 2 }} />

            {/* 加载指示器 */}
            {modelLoading && (
                <Box
                    sx={{
                        position: 'absolute',
                        top: 0,
                        left: 0,
                        right: 0,
                        bottom: 0,
                        backgroundColor: 'rgba(0, 0, 0, 0.6)',
                        zIndex: 9999,
                        display: 'flex',
                        flexDirection: 'column',
                        alignItems: 'center',
                        justifyContent: 'center',
                        padding: 2,
                    }}
                >
                    <CircularProgress size={60} sx={{ color: 'white', mb: 3 }} />
                    <Typography variant="h6" color="white" gutterBottom align="center">
                        {modelLoadingText || '加载中...'}
                    </Typography>
                    <Typography variant="body2" color="white" align="center" sx={{ maxWidth: 400 }}>
                        大型模型加载可能需要一些时间，请耐心等待
                    </Typography>
                </Box>
            )}

            <Box sx={{ display: 'flex', flexDirection: 'row', height: '80vh', width: '100%' }}>
                {/* 3D编辑器 */}
                <Box sx={{ width: '80%', height: '100%', pr: 2 }}>
                    <Paper
                        elevation={1}
                        sx={{
                            width: '100%',
                            height: '100%',
                            overflow: 'hidden',
                            borderRadius: 2
                        }}
                    >
                        <ThreeModelScene
                            objects={objects}
                            selectedObject={selectedObject}
                            setSelectedObject={setSelectedObject}
                            previewObject={previewObject}
                            setPreviewObject={setPreviewObject}
                            onObjectPlaced={handleObjectPlaced}
                            onObjectRemoved={handleObjectRemoved}
                            showHelpers={showHelpers}
                            transformMode={transformMode}
                            externalModels={externalModels}
                        />
                    </Paper>

                    <Box sx={{ mt: 2, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                        <Typography variant="caption" color="text.secondary">
                            提示: 左键单击放置几何体，右键单击移除预览几何体，双击实体可将其转为预览状态
                        </Typography>
                    </Box>
                </Box>

                {/* 工具面板 */}
                <Box sx={{ width: '20%', height: '100%' }}>
                    <Paper elevation={1} sx={{ p: 2, borderRadius: 2, height: '100%', overflowY: 'auto' }}>
                        <Tabs
                            value={activeTab}
                            onChange={(e, newValue) => setActiveTab(newValue)}
                            variant="fullWidth"
                            sx={{ mb: 2 }}
                        >
                            <StyledTab label="属性" />
                            <StyledTab label="文件" />
                            <StyledTab label="视图" />
                        </Tabs>

                        {activeTab === 0 && (
                            <>
                                {selectedObject !== null ? (
                                    <>
                                        {/* 选中对象的属性 */}
                                        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
                                            <Typography variant="subtitle2" gutterBottom sx={{ mb: 0 }}>
                                                编辑选中对象 #{selectedObject + 1}
                                            </Typography>
                                            <Tooltip title="删除选中对象">
                                                <IconButton onClick={deleteSelectedObject} size="small" color="error">
                                                    <DeleteIcon />
                                                </IconButton>
                                            </Tooltip>
                                        </Box>

                                        <FormControl fullWidth margin="dense" size="small">
                                            <TextField
                                                label="颜色"
                                                type="color"
                                                value={selectedObjectColor}
                                                onChange={(e) => {
                                                    setSelectedObjectColor(e.target.value);
                                                    updateSelectedObject({ color: e.target.value });
                                                }}
                                                InputProps={{
                                                    startAdornment: (
                                                        <InputAdornment position="start">
                                                            <PaletteIcon style={{ color: selectedObjectColor }} />
                                                        </InputAdornment>
                                                    ),
                                                }}
                                                size="small"
                                            />
                                        </FormControl>

                                        {/* 为所有对象类型添加大小调整功能 */}
                                        <Box sx={{ mt: 2, mb: 2 }}>
                                            <Typography variant="subtitle2" gutterBottom>
                                                大小调整
                                            </Typography>

                                            {objects[selectedObject] && objects[selectedObject].type === 'external_model' ? (
                                                <>
                                                    <Typography variant="caption">
                                                        统一缩放: {objects[selectedObject].scale ? Math.round(objects[selectedObject].scale.x * 100) / 100 : 1}
                                                    </Typography>
                                                    <Slider
                                                        value={objects[selectedObject].scale ? objects[selectedObject].scale.x : 1}
                                                        onChange={(_, value) => {
                                                            const newScale = { x: value, y: value, z: value };
                                                            updateSelectedObject({ scale: newScale });
                                                        }}
                                                        min={0.1}
                                                        max={5}
                                                        step={0.1}
                                                        size="small"
                                                    />

                                                    <Divider sx={{ my: 1 }} />

                                                    <Typography variant="caption">
                                                        X轴缩放: {objects[selectedObject].scale ? Math.round(objects[selectedObject].scale.x * 100) / 100 : 1}
                                                    </Typography>
                                                    <Slider
                                                        value={objects[selectedObject].scale ? objects[selectedObject].scale.x : 1}
                                                        onChange={(_, value) => {
                                                            const currentScale = objects[selectedObject].scale || { x: 1, y: 1, z: 1 };
                                                            const newScale = { ...currentScale, x: value };
                                                            updateSelectedObject({ scale: newScale });
                                                        }}
                                                        min={0.1}
                                                        max={5}
                                                        step={0.1}
                                                        size="small"
                                                    />

                                                    <Typography variant="caption">
                                                        Y轴缩放: {objects[selectedObject].scale ? Math.round(objects[selectedObject].scale.y * 100) / 100 : 1}
                                                    </Typography>
                                                    <Slider
                                                        value={objects[selectedObject].scale ? objects[selectedObject].scale.y : 1}
                                                        onChange={(_, value) => {
                                                            const currentScale = objects[selectedObject].scale || { x: 1, y: 1, z: 1 };
                                                            const newScale = { ...currentScale, y: value };
                                                            updateSelectedObject({ scale: newScale });
                                                        }}
                                                        min={0.1}
                                                        max={5}
                                                        step={0.1}
                                                        size="small"
                                                    />

                                                    <Typography variant="caption">
                                                        Z轴缩放: {objects[selectedObject].scale ? Math.round(objects[selectedObject].scale.z * 100) / 100 : 1}
                                                    </Typography>
                                                    <Slider
                                                        value={objects[selectedObject].scale ? objects[selectedObject].scale.z : 1}
                                                        onChange={(_, value) => {
                                                            const currentScale = objects[selectedObject].scale || { x: 1, y: 1, z: 1 };
                                                            const newScale = { ...currentScale, z: value };
                                                            updateSelectedObject({ scale: newScale });
                                                        }}
                                                        min={0.1}
                                                        max={5}
                                                        step={0.1}
                                                        size="small"
                                                    />
                                                </>
                                            ) : (
                                                // 标准几何体的尺寸控制
                                                <>
                                                    {objects[selectedObject].type === 'box' && (
                                                        <>
                                                            <Typography variant="caption">
                                                                宽度: {objects[selectedObject].size.width}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].size.width}
                                                                onChange={(_, value) => {
                                                                    const newSize = {
                                                                        ...objects[selectedObject].size,
                                                                        width: value
                                                                    };
                                                                    updateSelectedObject({ size: newSize });
                                                                }}
                                                                min={0.1}
                                                                max={10}
                                                                step={0.1}
                                                                size="small"
                                                            />

                                                            <Typography variant="caption">
                                                                高度: {objects[selectedObject].size.height}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].size.height}
                                                                onChange={(_, value) => {
                                                                    const newSize = {
                                                                        ...objects[selectedObject].size,
                                                                        height: value
                                                                    };
                                                                    updateSelectedObject({ size: newSize });
                                                                }}
                                                                min={0.1}
                                                                max={10}
                                                                step={0.1}
                                                                size="small"
                                                            />

                                                            <Typography variant="caption">
                                                                深度: {objects[selectedObject].size.depth}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].size.depth}
                                                                onChange={(_, value) => {
                                                                    const newSize = {
                                                                        ...objects[selectedObject].size,
                                                                        depth: value
                                                                    };
                                                                    updateSelectedObject({ size: newSize });
                                                                }}
                                                                min={0.1}
                                                                max={10}
                                                                step={0.1}
                                                                size="small"
                                                            />
                                                        </>
                                                    )}

                                                    {objects[selectedObject].type === 'sphere' && (
                                                        <>
                                                            <Typography variant="caption">
                                                                半径: {objects[selectedObject].radius}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].radius}
                                                                onChange={(_, value) => {
                                                                    updateSelectedObject({ radius: value });
                                                                }}
                                                                min={0.1}
                                                                max={5}
                                                                step={0.1}
                                                                size="small"
                                                            />
                                                        </>
                                                    )}

                                                    {objects[selectedObject].type === 'cylinder' && (
                                                        <>
                                                            <Typography variant="caption">
                                                                半径: {objects[selectedObject].radius}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].radius}
                                                                onChange={(_, value) => {
                                                                    updateSelectedObject({ radius: value });
                                                                }}
                                                                min={0.1}
                                                                max={5}
                                                                step={0.1}
                                                                size="small"
                                                            />

                                                            <Typography variant="caption">
                                                                高度: {objects[selectedObject].height}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].height}
                                                                onChange={(_, value) => {
                                                                    updateSelectedObject({ height: value });
                                                                }}
                                                                min={0.1}
                                                                max={10}
                                                                step={0.1}
                                                                size="small"
                                                            />
                                                        </>
                                                    )}

                                                    {objects[selectedObject].type === 'cone' && (
                                                        <>
                                                            <Typography variant="caption">
                                                                底部半径: {objects[selectedObject].radius}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].radius}
                                                                onChange={(_, value) => {
                                                                    updateSelectedObject({ radius: value });
                                                                }}
                                                                min={0.1}
                                                                max={5}
                                                                step={0.1}
                                                                size="small"
                                                            />

                                                            <Typography variant="caption">
                                                                高度: {objects[selectedObject].height}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].height}
                                                                onChange={(_, value) => {
                                                                    updateSelectedObject({ height: value });
                                                                }}
                                                                min={0.1}
                                                                max={10}
                                                                step={0.1}
                                                                size="small"
                                                            />
                                                        </>
                                                    )}

                                                    {objects[selectedObject].type === 'torus' && (
                                                        <>
                                                            <Typography variant="caption">
                                                                半径: {objects[selectedObject].radius}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].radius}
                                                                onChange={(_, value) => {
                                                                    updateSelectedObject({ radius: value });
                                                                }}
                                                                min={0.5}
                                                                max={5}
                                                                step={0.1}
                                                                size="small"
                                                            />

                                                            <Typography variant="caption">
                                                                管粗细: {objects[selectedObject].tube}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].tube}
                                                                onChange={(_, value) => {
                                                                    updateSelectedObject({ tube: value });
                                                                }}
                                                                min={0.1}
                                                                max={2}
                                                                step={0.05}
                                                                size="small"
                                                            />
                                                        </>
                                                    )}

                                                    {objects[selectedObject].type === 'pyramid' && (
                                                        <>
                                                            <Typography variant="caption">
                                                                宽度: {objects[selectedObject].size.width}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].size.width}
                                                                onChange={(_, value) => {
                                                                    const newSize = {
                                                                        ...objects[selectedObject].size,
                                                                        width: value
                                                                    };
                                                                    updateSelectedObject({ size: newSize });
                                                                }}
                                                                min={0.1}
                                                                max={5}
                                                                step={0.1}
                                                                size="small"
                                                            />

                                                            <Typography variant="caption">
                                                                高度: {objects[selectedObject].size.height}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].size.height}
                                                                onChange={(_, value) => {
                                                                    const newSize = {
                                                                        ...objects[selectedObject].size,
                                                                        height: value
                                                                    };
                                                                    updateSelectedObject({ size: newSize });
                                                                }}
                                                                min={0.1}
                                                                max={5}
                                                                step={0.1}
                                                                size="small"
                                                            />

                                                            <Typography variant="caption">
                                                                深度: {objects[selectedObject].size.depth}
                                                            </Typography>
                                                            <Slider
                                                                value={objects[selectedObject].size.depth}
                                                                onChange={(_, value) => {
                                                                    const newSize = {
                                                                        ...objects[selectedObject].size,
                                                                        depth: value
                                                                    };
                                                                    updateSelectedObject({ size: newSize });
                                                                }}
                                                                min={0.1}
                                                                max={5}
                                                                step={0.1}
                                                                size="small"
                                                            />
                                                        </>
                                                    )}
                                                </>
                                            )}
                                        </Box>

                                        {/* 添加旋转控制 */}
                                        <Typography variant="subtitle2" gutterBottom sx={{ mt: 2 }}>
                                            旋转控制
                                        </Typography>

                                        <Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 1 }}>
                                            <Button
                                                variant={transformMode === 'translate' ? 'contained' : 'outlined'}
                                                size="small"
                                                onClick={() => setTransformMode('translate')}
                                                sx={{ flexGrow: 1, mr: 1 }}
                                            >
                                                平移
                                            </Button>
                                            <Button
                                                variant={transformMode === 'rotate' ? 'contained' : 'outlined'}
                                                size="small"
                                                onClick={() => setTransformMode('rotate')}
                                                sx={{ flexGrow: 1 }}
                                            >
                                                旋转
                                            </Button>
                                        </Box>

                                        <Typography variant="caption">
                                            X轴旋转: {Math.round(selectedObjectRotation.x * 180 / Math.PI)}°
                                        </Typography>
                                        <Slider
                                            value={selectedObjectRotation.x * 180 / Math.PI}
                                            onChange={(_, value) => {
                                                const newRotation = {
                                                    ...selectedObjectRotation,
                                                    x: value * Math.PI / 180
                                                };
                                                setSelectedObjectRotation(newRotation);
                                                updateSelectedObject({ rotation: newRotation });
                                            }}
                                            min={-180}
                                            max={180}
                                            step={5}
                                            size="small"
                                        />

                                        <Typography variant="caption">
                                            Y轴旋转: {Math.round(selectedObjectRotation.y * 180 / Math.PI)}°
                                        </Typography>
                                        <Slider
                                            value={selectedObjectRotation.y * 180 / Math.PI}
                                            onChange={(_, value) => {
                                                const newRotation = {
                                                    ...selectedObjectRotation,
                                                    y: value * Math.PI / 180
                                                };
                                                setSelectedObjectRotation(newRotation);
                                                updateSelectedObject({ rotation: newRotation });
                                            }}
                                            min={-180}
                                            max={180}
                                            step={5}
                                            size="small"
                                        />

                                        <Typography variant="caption">
                                            Z轴旋转: {Math.round(selectedObjectRotation.z * 180 / Math.PI)}°
                                        </Typography>
                                        <Slider
                                            value={selectedObjectRotation.z * 180 / Math.PI}
                                            onChange={(_, value) => {
                                                const newRotation = {
                                                    ...selectedObjectRotation,
                                                    z: value * Math.PI / 180
                                                };
                                                setSelectedObjectRotation(newRotation);
                                                updateSelectedObject({ rotation: newRotation });
                                            }}
                                            min={-180}
                                            max={180}
                                            step={5}
                                            size="small"
                                        />

                                        <Divider sx={{ my: 2 }} />
                                    </>
                                ) : null}

                                {/* 几何体属性 */}
                                <Typography variant="subtitle2" gutterBottom>
                                    新对象属性
                                </Typography>

                                <FormControl fullWidth margin="dense" size="small">
                                    <InputLabel>对象类型</InputLabel>
                                    <Select
                                        value={newObjectType}
                                        onChange={(e) => {
                                            setNewObjectType(e.target.value);
                                            if (previewObject) {
                                                createPreviewObject();
                                            }
                                        }}
                                        label="对象类型"
                                    >
                                        <MenuItem value="box">立方体</MenuItem>
                                        <MenuItem value="sphere">球体</MenuItem>
                                        <MenuItem value="cylinder">圆柱体</MenuItem>
                                        <MenuItem value="cone">圆锥体</MenuItem>
                                        <MenuItem value="torus">圆环</MenuItem>
                                        <MenuItem value="pyramid">金字塔</MenuItem>
                                    </Select>
                                </FormControl>

                                <FormControl fullWidth margin="dense" size="small">
                                    <TextField
                                        label="颜色"
                                        type="color"
                                        value={newObjectColor}
                                        onChange={(e) => {
                                            setNewObjectColor(e.target.value);
                                            if (previewObject) {
                                                setPreviewObject(prev => ({
                                                    ...prev,
                                                    color: e.target.value
                                                }));
                                            }
                                        }}
                                        InputProps={{
                                            startAdornment: (
                                                <InputAdornment position="start">
                                                    <PaletteIcon style={{ color: newObjectColor }} />
                                                </InputAdornment>
                                            ),
                                        }}
                                        size="small"
                                    />
                                </FormControl>

                                {newObjectType === 'box' && (
                                    <>
                                        <Typography variant="caption" sx={{ mt: 1 }}>
                                            长度: {boxSize.width}
                                        </Typography>
                                        <Slider
                                            value={boxSize.width}
                                            onChange={(_, value) => {
                                                setBoxSize({ ...boxSize, width: value });
                                                if (previewObject && previewObject.type === 'box') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        size: { ...prev.size, width: value }
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={5}
                                            step={0.1}
                                            size="small"
                                        />

                                        <Typography variant="caption">
                                            高度: {boxSize.height}
                                        </Typography>
                                        <Slider
                                            value={boxSize.height}
                                            onChange={(_, value) => {
                                                setBoxSize({ ...boxSize, height: value });
                                                if (previewObject && previewObject.type === 'box') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        size: { ...prev.size, height: value }
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={5}
                                            step={0.1}
                                            size="small"
                                        />

                                        <Typography variant="caption">
                                            深度: {boxSize.depth}
                                        </Typography>
                                        <Slider
                                            value={boxSize.depth}
                                            onChange={(_, value) => {
                                                setBoxSize({ ...boxSize, depth: value });
                                                if (previewObject && previewObject.type === 'box') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        size: { ...prev.size, depth: value }
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={5}
                                            step={0.1}
                                            size="small"
                                        />
                                    </>
                                )}

                                {newObjectType === 'sphere' && (
                                    <>
                                        <Typography variant="caption" sx={{ mt: 1 }}>
                                            半径: {sphereRadius}
                                        </Typography>
                                        <Slider
                                            value={sphereRadius}
                                            onChange={(_, value) => {
                                                setSphereRadius(value);
                                                if (previewObject && previewObject.type === 'sphere') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        radius: value
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={5}
                                            step={0.1}
                                            size="small"
                                        />
                                    </>
                                )}

                                {newObjectType === 'cylinder' && (
                                    <>
                                        <Typography variant="caption" sx={{ mt: 1 }}>
                                            半径: {cylinderSize.radius}
                                        </Typography>
                                        <Slider
                                            value={cylinderSize.radius}
                                            onChange={(_, value) => {
                                                setCylinderSize({ ...cylinderSize, radius: value });
                                                if (previewObject && previewObject.type === 'cylinder') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        radius: value
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={5}
                                            step={0.1}
                                            size="small"
                                        />

                                        <Typography variant="caption">
                                            高度: {cylinderSize.height}
                                        </Typography>
                                        <Slider
                                            value={cylinderSize.height}
                                            onChange={(_, value) => {
                                                setCylinderSize({ ...cylinderSize, height: value });
                                                if (previewObject && previewObject.type === 'cylinder') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        height: value
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={10}
                                            step={0.1}
                                            size="small"
                                        />
                                    </>
                                )}

                                {newObjectType === 'cone' && (
                                    <>
                                        <Typography variant="caption" sx={{ mt: 1 }}>
                                            底部半径: {coneSize.radius}
                                        </Typography>
                                        <Slider
                                            value={coneSize.radius}
                                            onChange={(_, value) => {
                                                setConeSize({ ...coneSize, radius: value });
                                                if (previewObject && previewObject.type === 'cone') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        radius: value
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={5}
                                            step={0.1}
                                            size="small"
                                        />

                                        <Typography variant="caption">
                                            高度: {coneSize.height}
                                        </Typography>
                                        <Slider
                                            value={coneSize.height}
                                            onChange={(_, value) => {
                                                setConeSize({ ...coneSize, height: value });
                                                if (previewObject && previewObject.type === 'cone') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        height: value
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={10}
                                            step={0.1}
                                            size="small"
                                        />
                                    </>
                                )}

                                {newObjectType === 'torus' && (
                                    <>
                                        <Typography variant="caption" sx={{ mt: 1 }}>
                                            半径: {torusSize.radius}
                                        </Typography>
                                        <Slider
                                            value={torusSize.radius}
                                            onChange={(_, value) => {
                                                setTorusSize({ ...torusSize, radius: value });
                                                if (previewObject && previewObject.type === 'torus') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        radius: value
                                                    }));
                                                }
                                            }}
                                            min={0.5}
                                            max={5}
                                            step={0.1}
                                            size="small"
                                        />

                                        <Typography variant="caption">
                                            管粗细: {torusSize.tube}
                                        </Typography>
                                        <Slider
                                            value={torusSize.tube}
                                            onChange={(_, value) => {
                                                setTorusSize({ ...torusSize, tube: value });
                                                if (previewObject && previewObject.type === 'torus') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        tube: value
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={2}
                                            step={0.05}
                                            size="small"
                                        />
                                    </>
                                )}

                                {newObjectType === 'pyramid' && (
                                    <>
                                        <Typography variant="caption" sx={{ mt: 1 }}>
                                            宽度: {pyramidSize.width}
                                        </Typography>
                                        <Slider
                                            value={pyramidSize.width}
                                            onChange={(_, value) => {
                                                setPyramidSize({ ...pyramidSize, width: value });
                                                if (previewObject && previewObject.type === 'pyramid') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        size: { ...prev.size, width: value }
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={5}
                                            step={0.1}
                                            size="small"
                                        />

                                        <Typography variant="caption">
                                            高度: {pyramidSize.height}
                                        </Typography>
                                        <Slider
                                            value={pyramidSize.height}
                                            onChange={(_, value) => {
                                                setPyramidSize({ ...pyramidSize, height: value });
                                                if (previewObject && previewObject.type === 'pyramid') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        size: { ...prev.size, height: value }
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={5}
                                            step={0.1}
                                            size="small"
                                        />

                                        <Typography variant="caption">
                                            深度: {pyramidSize.depth}
                                        </Typography>
                                        <Slider
                                            value={pyramidSize.depth}
                                            onChange={(_, value) => {
                                                setPyramidSize({ ...pyramidSize, depth: value });
                                                if (previewObject && previewObject.type === 'pyramid') {
                                                    setPreviewObject(prev => ({
                                                        ...prev,
                                                        size: { ...prev.size, depth: value }
                                                    }));
                                                }
                                            }}
                                            min={0.1}
                                            max={5}
                                            step={0.1}
                                            size="small"
                                        />
                                    </>
                                )}

                                <Button
                                    fullWidth
                                    variant="contained"
                                    color="primary"
                                    startIcon={<AddIcon />}
                                    onClick={() => {
                                        createPreviewObject();
                                        // 创建几何体并直接添加到场景
                                        const position = { x: 0, y: 1, z: 0 }; // 默认位置
                                        if (previewObject) {
                                            const newObject = { ...previewObject, position };
                                            handleObjectPlaced(newObject);
                                            setPreviewObject(null);
                                        }
                                    }}
                                    sx={{ mt: 2 }}
                                >
                                    创建模型
                                </Button>
                            </>
                        )}

                        {activeTab === 1 && (
                            <>
                                <Typography variant="subtitle2" gutterBottom fontSize="0.8rem">
                                    导入/导出
                                </Typography>

                                <Stack spacing={1}>
                                    <Button
                                        variant="outlined"
                                        startIcon={<FileUploadIcon />}
                                        onClick={handleFileUploadClick}
                                        size="small"
                                        sx={{ fontSize: '0.75rem' }}
                                    >
                                        导入模型
                                    </Button>

                                    <Button
                                        variant="outlined"
                                        startIcon={<FileDownloadIcon />}
                                        onClick={handleExportClick}
                                        disabled={downloadInProgress || objects.length === 0}
                                        size="small"
                                        sx={{ fontSize: '0.75rem' }}
                                    >
                                        导出模型
                                    </Button>

                                    <Button
                                        variant="contained"
                                        color="success"
                                        startIcon={<SaveIcon />}
                                        onClick={handleSave}
                                        disabled={objects.length === 0}
                                        size="small"
                                        sx={{ fontSize: '0.75rem' }}
                                    >
                                        保存模型
                                    </Button>
                                </Stack>

                                <Divider sx={{ my: 1 }} />

                                <Typography variant="subtitle2" gutterBottom fontSize="0.8rem">
                                    文件格式
                                </Typography>

                                <FormControl fullWidth size="small" sx={{ mb: 1 }}>
                                    <Select
                                        value={exportFormat}
                                        onChange={(e) => setExportFormat(e.target.value)}
                                        size="small"
                                    >
                                        <MenuItem value="json">JSON模型</MenuItem>
                                        <MenuItem value="obj">OBJ格式</MenuItem>
                                        <MenuItem value="stl">STL格式</MenuItem>
                                        <MenuItem value="glb">GLB/GLTF格式</MenuItem>
                                    </Select>
                                </FormControl>

                                {downloadInProgress && (
                                    <Box sx={{ display: 'flex', alignItems: 'center', mt: 1 }}>
                                        <CircularProgress size={16} sx={{ mr: 1 }} />
                                        <Typography variant="caption">
                                            处理中...
                                        </Typography>
                                    </Box>
                                )}
                            </>
                        )}

                        {activeTab === 2 && (
                            <>
                                <Typography variant="subtitle2" gutterBottom fontSize="0.8rem">
                                    视图设置
                                </Typography>

                                <FormControlLabel
                                    control={
                                        <Switch
                                            checked={showHelpers}
                                            onChange={(e) => setShowHelpers(e.target.checked)}
                                            size="small"
                                        />
                                    }
                                    label={
                                        <Typography variant="caption">
                                            显示辅助工具
                                        </Typography>
                                    }
                                    sx={{ mb: 1 }}
                                />

                                <Typography variant="subtitle2" gutterBottom fontSize="0.8rem">
                                    编辑区高度
                                </Typography>

                                <Slider
                                    value={editorHeight}
                                    onChange={(_, value) => setEditorHeight(value)}
                                    min={400}
                                    max={800}
                                    step={50}
                                    size="small"
                                    marks={[
                                        { value: 400, label: '400' },
                                        { value: 600, label: '600' },
                                        { value: 800, label: '800' },
                                    ]}
                                    sx={{ mb: 2 }}
                                />
                            </>
                        )}
                    </Paper>
                </Box>
            </Box>

            {/* 隐藏的文件输入 */}
            <input
                type="file"
                ref={fileInputRef}
                onChange={importModel}
                style={{ display: 'none' }}
                accept=".json,.obj,.stl,.glb"
            />

            {/* 导出格式菜单 */}
            <Menu
                anchorEl={downloadMenuAnchor}
                open={Boolean(downloadMenuAnchor)}
                onClose={handleCloseDownloadMenu}
                anchorOrigin={{
                    vertical: 'bottom',
                    horizontal: 'right',
                }}
                transformOrigin={{
                    vertical: 'top',
                    horizontal: 'right',
                }}
            >
                <MenuItem onClick={exportJsonModel}>
                    <ListItemIcon>
                        <FileDownloadIcon fontSize="small" />
                    </ListItemIcon>
                    <ListItemText>JSON格式</ListItemText>
                </MenuItem>
                <MenuItem onClick={() => exportModelAs('obj')}>
                    <ListItemIcon>
                        <ViewInArIcon fontSize="small" />
                    </ListItemIcon>
                    <ListItemText>OBJ格式</ListItemText>
                </MenuItem>
                <MenuItem onClick={() => exportModelAs('stl')}>
                    <ListItemIcon>
                        <ViewInArIcon fontSize="small" />
                    </ListItemIcon>
                    <ListItemText>STL格式</ListItemText>
                </MenuItem>
                <MenuItem onClick={() => exportModelAs('glb')}>
                    <ListItemIcon>
                        <ViewInArIcon fontSize="small" />
                    </ListItemIcon>
                    <ListItemText>GLB格式</ListItemText>
                </MenuItem>
            </Menu>
        </Paper>
    );
};

export default ThreeModelEditor; 